home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / pygtk / 2.0 / demos / pixbufs.py < prev    next >
Text File  |  2006-01-20  |  6KB  |  196 lines

  1. #!/usr/bin/env python
  2. '''Pixbufs
  3.  
  4. A GdkPixbuf represents an image, normally in RGB or RGBA format.
  5. Pixbufs are normally used to load files from disk and perform image scaling.
  6. This demo is not all that educational, but looks cool. It was written by
  7. Extreme Pixbuf Hacker Federico Mena Quintero. It also shows off how to use
  8. GtkDrawingArea to do a simple animation.
  9. Look at the Image demo for additional pixbuf usage examples.'''
  10. # pygtk version: Maik Hertha <maik.hertha@berlin.de>
  11.  
  12. import os
  13. import math
  14. import gobject
  15. import gtk
  16.  
  17. FRAME_DELAY = 50
  18. CYCLE_LEN = 60
  19. IMAGE_DIR = os.path.join(os.path.dirname(__file__), 'images')
  20. BACKGROUND_NAME = "background.jpg"
  21.  
  22. image_names = [
  23.     "apple-red.png",
  24.     "gnome-applets.png",
  25.     "gnome-calendar.png",
  26.     "gnome-foot.png",
  27.     "gnome-gmush.png",
  28.     "gnome-gimp.png",
  29.     "gnome-gsame.png",
  30.     "gnu-keys.png"
  31. ]
  32.  
  33. class PixbufsDemo(gtk.Window):
  34.     frame  = None      # frame of the background image
  35.     background = None  # background-pixbuf
  36.     images     = []    # list of pixbufs
  37.     back_width  = 0    # width of background image
  38.     back_height = 0    # height of background image
  39.     timeout_id  = 0    # timeout id
  40.     frame_num   = 0    # number of the current frame
  41.     timeout_id = None
  42.  
  43.     def __init__(self, parent=None):
  44.         gtk.Window.__init__(self)
  45.         try:
  46.             self.set_screen(parent.get_screen())
  47.         except AttributeError:
  48.             self.connect("destroy", lambda *w: gtk.main_quit())
  49.         self.connect("destroy", self.cleanup_callback)
  50.         self.set_title(self.__class__.__name__)
  51.         self.set_resizable(False)
  52.  
  53.         if not self.load_pixbufs():
  54.             dialog = gtk.MessageDialog(self,
  55.                 gtk.DIALOG_DESTROY_WITH_PARENT,
  56.                 gtk.MESSAGE_ERROR,
  57.                 gtk.BUTTONS_CLOSE,
  58.                 "Failed to load an image")
  59.             dialog.connect("response", lambda d, r: dlg.destroy())
  60.             dialog.show()
  61.  
  62.         else:
  63.             self.set_size_request(self.back_width, self.back_height)
  64.  
  65.             self.frame = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
  66.                 self.back_width, self.back_height)
  67.  
  68.             da = gtk.DrawingArea()
  69.             da.connect("expose_event", self.expose_cb)
  70.             self.add(da)
  71.  
  72.             self.timeout_id = gtk.timeout_add(FRAME_DELAY, self.timeout)
  73.  
  74.             self.show_all()
  75.  
  76.     def load_pixbufs(self):
  77.         ''' Loads the images for the demo and returns whether the
  78.             operation succeeded.
  79.         '''
  80.         if self.background is not None:
  81.             return True   # already loaded earlier
  82.  
  83.         # look in the the current directory where the file is installed
  84.         try:
  85.             self.background = gtk.gdk.pixbuf_new_from_file(
  86.                 os.path.join(IMAGE_DIR, BACKGROUND_NAME))
  87.         except gobject.GError, error:
  88.             return False
  89.  
  90.         self.back_width  = self.background.get_width()
  91.         self.back_height = self.background.get_height()
  92.  
  93.         for filename in image_names:
  94.             try:
  95.                 self.images.append(gtk.gdk.pixbuf_new_from_file(
  96.                     os.path.join(IMAGE_DIR, filename)))
  97.             except gobject.GError, error:
  98.                 return False
  99.  
  100.         return True
  101.  
  102.     def expose_cb(self, draw_area, event):
  103.         ''' Expose callback for the drawing area. '''
  104.         rowstride = self.frame.get_rowstride()
  105.  
  106.         # FIXME: what should be the result, string guchar an integer result?
  107.         #pixels = frame.get_pixels() + rowstride * event.area.y + event.area.x * 3
  108.         #pixels = frame.get_pixels()[len(frame.get_pixels()) + rowstride * event.area.y + event.area.x * 3]
  109.         pixels = self.frame.get_pixels()
  110.  
  111.         # FIXME: draw_rgb_image_dithalign seems not to be available
  112.         #draw_area.window.draw_rgb_image_dithalign(widget.style.black_gc,
  113.         draw_area.window.draw_rgb_image(
  114.             draw_area.style.black_gc,
  115.             event.area.x, event.area.y,
  116.             event.area.width, event.area.height,
  117.             'normal',
  118.             pixels, rowstride,
  119.             event.area.x, event.area.y)
  120.  
  121.         return True
  122.  
  123.     def cleanup_callback(self, win):
  124.         if self.timeout_id is not None:
  125.             gtk.timeout_remove(self.timeout_id)
  126.             self.timeout_id = None
  127.  
  128.     def timeout(self):
  129.         ''' Timeout handler to regenerate the frame. '''
  130.         self.background.copy_area(0, 0, self.back_width, self.back_height,
  131.             self.frame, 0, 0)
  132.  
  133.         f = float(self.frame_num % CYCLE_LEN) / float(CYCLE_LEN)
  134.  
  135.         xmid = self.back_width / 2.0
  136.         ymid = self.back_height / 2.0
  137.  
  138.         radius = min(xmid, ymid) / 2.0
  139.  
  140.         N_IMAGES = len(image_names)
  141.         for i_name in image_names:
  142.             i = image_names.index(i_name)
  143.  
  144.             ang = 2.0 * math.pi * i / N_IMAGES - f * 2.0 * math.pi
  145.  
  146.             iw = self.images[i].get_width()
  147.             ih = self.images[i].get_height()
  148.  
  149.             r = radius +(radius / 3.0) * math.sin(f * 2.0 * math.pi)
  150.  
  151.             xpos = math.floor(xmid + r * math.cos(ang) - iw / 2.0 + 0.5)
  152.             ypos = math.floor(ymid + r * math.sin(ang) - ih / 2.0 + 0.5)
  153.  
  154.             k = (i & 1) and math.sin(f * 2.0 * math.pi) or math.cos(f * 2.0 * math.pi)
  155.             k = 2.0 * k * k
  156.             k = max(0.25, k)
  157.  
  158.             # satisfy the c-source
  159.             r1 = gtk.gdk.Rectangle()
  160.             r1.x = int(xpos)
  161.             r1.y = int(ypos)
  162.             r1.width  = iw * k
  163.             r1.height = ih * k
  164.  
  165.             r2 = gtk.gdk.Rectangle()
  166.             r2.x = 0
  167.             r2.y = 0
  168.             r2.width  = self.back_width
  169.             r2.height = self.back_height
  170.  
  171.             dest = r1.intersect(r2)
  172.             if dest is not None:
  173.                 self.images[i].composite(
  174.                       self.frame,
  175.                       dest.x, dest.y,
  176.                       dest.width, dest.height,
  177.                       xpos, ypos,
  178.                       k, k,
  179.                       gtk.gdk.INTERP_NEAREST,
  180.                       ((i & 1)
  181.                        and int(max(127, math.fabs(255 * math.sin(f * 2.0 * math.pi))))
  182.                        or  int(max(127, math.fabs(255 * math.cos(f * 2.0 * math.pi))))))
  183.  
  184.         if self is not None:
  185.             self.queue_draw()
  186.  
  187.         self.frame_num += 1
  188.         return True
  189.  
  190. def main():
  191.     PixbufsDemo()
  192.     gtk.main()
  193.  
  194. if __name__ == '__main__':
  195.     main()
  196.